home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_08 / phillip2 / segment2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-14  |  26.4 KB  |  932 lines

  1.  
  2.  
  3.  
  4.        /***********************************************
  5.        *
  6.        *       file d:\cips\segment2.c
  7.        *
  8.        *       Functions: This file contains
  9.        *          find_cutoff_point
  10.        *          edge_region
  11.        *          gray_shade_region
  12.        *          edge_gray_shade_region
  13.        *          pixel_grow
  14.        *          pixel_label_and_check_neighbors
  15.        *          is_close
  16.        *          erode_image_array
  17.        *          get_edge_region_options
  18.        *
  19.        *       Purpose:
  20.        *          These function implement the three
  21.        *          segmentation techniques in Image
  22.        *          Processing part 10.
  23.        *
  24.        *       External Calls:
  25.        *          wtiff.c - round_off_image_size
  26.        *                    create_file_if_needed
  27.        *                    write_array_into_tiff_image
  28.        *          tiff.c - read_tiff_header
  29.        *          rtiff.c - read_tiff_image
  30.        *          numcvrt.c - get_integer
  31.        *          edges.c - quick_edge
  32.        *                    homogeneity
  33.        *                    difference_edge
  34.        *                    contrast_edge
  35.        *                    gaussian_edge
  36.        *                    range
  37.        *                    variance
  38.        *                    detect_edges
  39.        *          hist.c - calculate_histogram
  40.        *                   zero_histogram
  41.        *          thresh.c - threshold_image_array
  42.        *
  43.        *       Modifications:
  44.        *          5 December 1992 - created
  45.        *
  46.        *************************************************/
  47.  
  48. #include "cips.h"
  49.  
  50.  
  51.  
  52.      /*******************************************
  53.      *
  54.      *   find_cutoff_point(..
  55.      *
  56.      *   This function looks at a histogram
  57.      *   and sets a cuttoff point at a given
  58.      *   percentage of pixels.
  59.      *   For example, if percent=0.6, you
  60.      *   start at 0 in the histogram and count
  61.      *   up until you've hit 60% of the pixels.
  62.      *   Then you stop and return that pixel
  63.      *   value.
  64.      *
  65.      ********************************************/
  66.  
  67. find_cutoff_point(histogram, percent, cutoff)
  68.    unsigned long histogram[];
  69.    float    percent;
  70.    short    *cutoff;
  71. {
  72.    float  fd, fsum, sum_div;
  73.    int    i, looking;
  74.    long   lc, lr, num=0, sum=0;
  75.  
  76.    sum     = 0;
  77.    i       = 0;
  78.    lr      = (long)(ROWS);
  79.    lc      = (long)(COLS);
  80.    num     = lr*lc;
  81.    fd      = (float)(num);
  82.  
  83.    while(looking){
  84.       fsum    = (float)(sum);
  85.       sum_div = fsum/fd;
  86.       if(sum_div >= percent)
  87.          looking = 0;
  88.       else
  89.          sum = sum + histogram[i++];
  90.    }  /* ends while looking */
  91.  
  92.    if(i >= 256) i = 255;
  93.    *cutoff = i;
  94.    printf("\nCutoff is %d sum=%ld", *cutoff, sum);
  95. }  /* ends find_cutoff_point */
  96.  
  97.  
  98.  
  99.  
  100.  
  101.      /*******************************************
  102.      *
  103.      *   edge_region(..
  104.      *
  105.      *   This function segments an image by
  106.      *   growing regions inside of edges.
  107.      *   The steps are:
  108.      *      . detect edges
  109.      *      . threshold edge output to a
  110.      *        percent value
  111.      *      . remove edges from consideration
  112.      *      . grow regions
  113.      *
  114.      *******************************************/
  115.  
  116.  
  117. edge_region(in_name, out_name, the_image, out_image,
  118.             il, ie, ll, le, edge_type, min_area,
  119.             max_area, diff, percent, set_value,
  120.             erode)
  121.    char     in_name[], out_name[];
  122.    float    percent;
  123.    int      edge_type, il, ie, ll, le;
  124.    short    diff, erode, 
  125.             max_area, min_area, 
  126.             set_value,
  127.             the_image[ROWS][COLS],
  128.             out_image[ROWS][COLS];
  129. {
  130.  
  131.    int    a, b, count, i, j, k,
  132.           length, width;
  133.    short  cutoff;
  134.    struct tiff_header_struct image_header;
  135.    unsigned long histogram[GRAY_LEVELS+1];
  136.  
  137.  
  138.    create_file_if_needed(in_name, out_name, out_image);
  139.  
  140.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  141.  
  142.       /***************************
  143.       *
  144.       *   Detect the edges.  Do
  145.       *   not threshold.
  146.       *
  147.       ****************************/
  148.  
  149.    if(edge_type == 1  ||
  150.       edge_type == 2  ||
  151.       edge_type == 3)
  152.       detect_edges(in_name, out_name, the_image,
  153.                    out_image, il, ie, ll, le,
  154.                    edge_type, 0, 0);
  155.  
  156.    if(edge_type == 4){
  157.       quick_edge(in_name, out_name, the_image,
  158.                  out_image, il, ie, ll, le,
  159.                  0, 0);
  160.    }  /* ends if 4 */
  161.  
  162.    if(edge_type == 5){
  163.       homogeneity(in_name, out_name, the_image,
  164.                  out_image, il, ie, ll, le,
  165.                  0, 0);
  166.    }  /* ends if 5 */
  167.  
  168.    if(edge_type == 6){
  169.       difference_edge(in_name, out_name, the_image,
  170.                  out_image, il, ie, ll, le,
  171.                  0, 0);
  172.    }  /* ends if 6 */
  173.  
  174.    if(edge_type == 7){
  175.       contrast_edge(in_name, out_name, the_image,
  176.                  out_image, il, ie, ll, le,
  177.                  0, 0);
  178.    }  /* ends if 7 */
  179.  
  180.    if(edge_type == 8){
  181.       gaussian_edge(in_name, out_name, the_image,
  182.                  out_image, il, ie, ll, le,
  183.                  3, 0, 0);
  184.    }  /* ends if 8 */
  185.  
  186.    if(edge_type == 10){
  187.       range(in_name, out_name, the_image,
  188.             out_image, il, ie, ll, le,
  189.             3, 0, 0);
  190.    }  /* ends if 10 */
  191.  
  192.    if(edge_type == 11){
  193.       variance(in_name, out_name, the_image,
  194.                out_image, il, ie, ll, le,
  195.                0, 0);
  196.    }  /* ends if 11 */
  197.  
  198. /**write_array_into_tiff_image("f:e1.tif", out_image,
  199. il, ie, ll, le);**/
  200.  
  201.       /* copy out_image to the_image */
  202.    for(i=0; i<ROWS; i++)
  203.       for(j=0; j<COLS; j++)
  204.          the_image[i][j] = out_image[i][j];
  205.  
  206.       /******************************
  207.       *
  208.       *   Threshold the edge detector
  209.       *   output at a given percent.
  210.       *   This eliminates the weak
  211.       *   edges.
  212.       *
  213.       *******************************/
  214.    zero_histogram(histogram);
  215.    calculate_histogram(the_image, histogram);
  216.    find_cutoff_point(histogram, percent, &cutoff);
  217.    threshold_image_array(the_image, out_image,
  218.                          255, cutoff, set_value);
  219. /**write_array_into_tiff_image("f:e2.tif", out_image,
  220. il, ie, ll, le);**/
  221.  
  222.    if(erode != 0){
  223.          /* copy out_image to the_image */
  224.       for(i=0; i<ROWS; i++)
  225.          for(j=0; j<COLS; j++)
  226.             the_image[i][j] = out_image[i][j];
  227.       erode_image_array(the_image, out_image,
  228.                         set_value, erode);
  229.    }  /* ends if erode */
  230.  
  231. /**write_array_into_tiff_image("f:e3.tif", out_image,
  232. il, ie, ll, le);**/
  233.  
  234.       /*******************************
  235.       *
  236.       *   Set all the edge values to
  237.       *   FORGET_IT so the region
  238.       *   growing will not use those
  239.       *   points.
  240.       *
  241.       *******************************/
  242.  
  243.    for(i=0; i<ROWS; i++)
  244.       for(j=0; j<COLS; j++)
  245.          if(out_image[i][j] == set_value)
  246.             out_image[i][j] = FORGET_IT;
  247.  
  248.    for(i=0; i<ROWS; i++)
  249.       for(j=0; j<COLS; j++)
  250.          the_image[i][j] = out_image[i][j];
  251.  
  252.    pixel_grow(the_image, out_image, diff,
  253.               min_area, max_area);
  254.  
  255.    write_array_into_tiff_image(out_name, out_image,
  256.                                il, ie, ll, le);
  257.  
  258. }  /* ends edge_region */
  259.  
  260.  
  261.  
  262.      /*******************************************
  263.      *
  264.      *   gray_shade_region(...
  265.      *
  266.      *   This function segments an image by
  267.      *   growing regions based only on gray
  268.      *   shade.
  269.      *
  270.      *******************************************/
  271.  
  272.  
  273. gray_shade_region(in_name, out_name, the_image,
  274.                   out_image, il, ie, ll, le,
  275.                   diff, min_area, max_area)
  276.    char   in_name[], out_name[];
  277.    int    il, ie, ll, le;
  278.    short  the_image[ROWS][COLS],
  279.           out_image[ROWS][COLS],
  280.           diff, min_area, max_area;
  281. {
  282.    int    a, b, big_count, count, i, j, k, l,
  283.           not_finished, length, width;
  284.    short  temp[3][3];
  285.    struct tiff_header_struct image_header;
  286.  
  287.    create_file_if_needed(in_name, out_name, out_image);
  288.  
  289.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  290.    pixel_grow(the_image, out_image, diff,
  291.               min_area, max_area);
  292.    write_array_into_tiff_image(out_name, out_image,
  293.                                il, ie, ll, le);
  294.  
  295. }  /* ends gray_shade_region */
  296.  
  297.  
  298.  
  299.  
  300.  
  301.      /*******************************************
  302.      *
  303.      *   edge_gray_shade_region(..
  304.      *
  305.      *   This function segments an image by
  306.      *   growing gray shade regions inside of
  307.      *   edges.  It combines the techniques
  308.      *   of the edge_region and gray_shade_region
  309.      *   functions.
  310.      *
  311.      *   The steps are:
  312.      *      . detect edges
  313.      *      . threshold edge output to a
  314.      *        percent value
  315.      *      . lay the edges on top of the original
  316.      *        image to eliminate them from
  317.      *        consideration
  318.      *      . grow regions
  319.      *
  320.      *******************************************/
  321.  
  322. edge_gray_shade_region(in_name, out_name, the_image,
  323.             out_image, il, ie, ll, le, edge_type,
  324.             min_area, max_area, diff, percent,
  325.             set_value, erode)
  326.    char     in_name[], out_name[];
  327.    float    percent;
  328.    int      edge_type, il, ie, ll, le;
  329.    short    diff, erode, 
  330.             max_area, min_area, 
  331.             set_value,
  332.             the_image[ROWS][COLS],
  333.             out_image[ROWS][COLS];
  334. {
  335.    int    a, b, count, i, j, k,
  336.           length, width;
  337.    short  cutoff;
  338.    struct tiff_header_struct image_header;
  339.    unsigned long histogram[GRAY_LEVELS+1];
  340.  
  341.    create_file_if_needed(in_name, out_name, out_image);
  342.  
  343.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  344.  
  345.       /***************************
  346.       *
  347.       *   Detect the edges.  Do
  348.       *   not threshold.
  349.       *
  350.       ****************************/
  351.  
  352.    if(edge_type == 1  ||
  353.       edge_type == 2  ||
  354.       edge_type == 3)
  355.       detect_edges(in_name, out_name, the_image,
  356.                    out_image, il, ie, ll, le,
  357.                    edge_type, 0, 0);
  358.  
  359.    if(edge_type == 4){
  360.       quick_edge(in_name, out_name, the_image,
  361.                  out_image, il, ie, ll, le,
  362.                  0, 0);
  363.    }  /* ends if 4 */
  364.    if(edge_type == 5){
  365.       homogeneity(in_name, out_name, the_image,
  366.                  out_image, il, ie, ll, le,
  367.                  0, 0);
  368.    }  /* ends if 5 */
  369.  
  370.    if(edge_type == 6){
  371.       difference_edge(in_name, out_name, the_image,
  372.                  out_image, il, ie, ll, le,
  373.                  0, 0);
  374.    }  /* ends if 6 */
  375.  
  376.    if(edge_type == 7){
  377.       contrast_edge(in_name, out_name, the_image,
  378.                  out_image, il, ie, ll, le,
  379.                  0, 0);
  380.    }  /* ends if 7 */
  381.  
  382.    if(edge_type == 8){
  383.       gaussian_edge(in_name, out_name, the_image,
  384.                  out_image, il, ie, ll, le,
  385.                  3, 0, 0);
  386.    }  /* ends if 8 */
  387.  
  388.    if(edge_type == 10){
  389.       range(in_name, out_name, the_image,
  390.             out_image, il, ie, ll, le,
  391.             3, 0, 0);
  392.    }  /* ends if 10 */
  393.  
  394.    if(edge_type == 11){
  395.       variance(in_name, out_name, the_image,
  396.                out_image, il, ie, ll, le,
  397.                0, 0);
  398.    }  /* ends if 11 */
  399.  
  400. /**write_array_into_tiff_image("f:e1.tif", out_image,
  401. il, ie, ll, le);**/
  402.  
  403.       /* copy out_image to the_image */
  404.    for(i=0; i<ROWS; i++)
  405.       for(j=0; j<COLS; j++)
  406.          the_image[i][j] = out_image[i][j];
  407.  
  408.       /******************************
  409.       *
  410.       *   Threshold the edge detector
  411.       *   output at a given percent.
  412.       *   This eliminates the weak
  413.       *   edges.
  414.       *
  415.       *******************************/
  416.  
  417.    zero_histogram(histogram);
  418.    calculate_histogram(the_image, histogram);
  419.    find_cutoff_point(histogram, percent, &cutoff);
  420.    threshold_image_array(the_image, out_image,
  421.                          255, cutoff, set_value);
  422.  
  423. /**write_array_into_tiff_image("f:e2.tif", out_image,
  424. il, ie, ll, le);**/
  425.  
  426.    if(erode != 0){
  427.          /* copy out_image to the_image */
  428.       for(i=0; i<ROWS; i++)
  429.          for(j=0; j<COLS; j++)
  430.             the_image[i][j] = out_image[i][j];
  431.       erode_image_array(the_image, out_image,
  432.                         set_value, erode);
  433.    }  /* ends if erode */
  434.  
  435. /**write_array_into_tiff_image("f:e3.tif", out_image,
  436. il, ie, ll, le);**/
  437.  
  438.       /*******************************
  439.       *
  440.       *   Read the original gray shade
  441.       *   image back into the_image.
  442.       *
  443.       *******************************/
  444.  
  445.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  446.  
  447.       /*******************************
  448.       *
  449.       *   Overlay the edge values
  450.       *   on top of the original
  451.       *   image by setting them to
  452.       *   FORGET_IT so the region
  453.       *   growing will not use those
  454.       *   points.
  455.       *
  456.       *******************************/
  457.  
  458.    for(i=0; i<ROWS; i++)
  459.       for(j=0; j<COLS; j++)
  460.          if(out_image[i][j] == set_value)
  461.             the_image[i][j] = FORGET_IT;
  462.  
  463. /**write_array_into_tiff_image("f:e4.tif", the_image,
  464. il, ie, ll, le);**/
  465.  
  466.    pixel_grow(the_image, out_image, diff,
  467.               min_area, max_area);
  468.  
  469.    write_array_into_tiff_image(out_name, out_image,
  470.                                il, ie, ll, le);
  471.  
  472. }  /* ends edge_gray_shade_region */
  473.  
  474.  
  475.  
  476.  
  477.     /**********************************************
  478.     *
  479.     *   pixel_grow(...
  480.     *
  481.     *   The function grows regions.  It is similar
  482.     *   to the grow function in segment.c, but it
  483.     *   has several new capabilities.  It can
  484.     *   eliminate regions if they are too large or
  485.     *   too small.
  486.     *
  487.     *   It ignores pixels = FORGET_IT.  This allows
  488.     *   it to ignore edges or regions already
  489.     *   eliminated from consideration.
  490.     *
  491.     *   It adds pixels to a growing region only if
  492.     *   the pixel is close enough to the average gray
  493.     *   level of that region.
  494.     *
  495.     ***********************************************/
  496.  
  497. pixel_grow(input, output, diff, min_area, max_area)
  498.    short input[ROWS][COLS],
  499.          output[ROWS][COLS],
  500.          max_area,
  501.          min_area,
  502.          diff;
  503. {
  504.    char name[80];
  505.  
  506.    int count,
  507.        first_call,
  508.        i,
  509.        ii,
  510.        j,
  511.        jj,
  512.        object_found,
  513.        pointer,
  514.        pop_i,
  515.        pop_j,
  516.        stack_empty,
  517.        stack_file_in_use;
  518.  
  519.    short g_label, target, sum, stack[STACK_SIZE][2];
  520.  
  521.    for(i=0; i<ROWS; i++)
  522.       for(j=0; j<COLS; j++)
  523.          output[i][j] = 0;
  524.  
  525.    g_label       = 2;
  526.    object_found  = 0;
  527.    first_call    = 1;
  528.  
  529.             /*************************************
  530.             *
  531.             *   Now begin the process of growing
  532.             *   regions.
  533.             *
  534.             **************************************/
  535.  
  536.    for(i=0; i<ROWS; i++){
  537. if( (i%4) == 0) printf("\n");
  538. printf("-i=%3d label=%3d", i, g_label);
  539.       for(j=0; j<COLS; j++){
  540.  
  541.          target            = input[i][j];
  542.          sum               = target;
  543.          count             = 0;
  544.          stack_file_in_use = 0;
  545.          stack_empty       = 1;
  546.          pointer           = -1;
  547.                /**********************************
  548.                *
  549.                *  Search for the first pixel of
  550.                *  a region.  It must not equal
  551.                *  FORGET_IT, and it must be close
  552.                *  enough to the target (ave value).
  553.                *
  554.                ***********************************/
  555.  
  556.          if(input[i][j] != FORGET_IT            &&
  557.             is_close(input[i][j], target, diff) &&
  558.             output[i][j] == 0){
  559.             pixel_label_and_check_neighbor(input,
  560.                            output, &target, &sum,
  561.                            &count, stack, g_label,
  562.                            &stack_empty, &pointer,
  563.                            i, j, diff,
  564.                            &stack_file_in_use,
  565.                            &first_call);
  566.             object_found = 1;
  567.          }  /* ends if is_close */
  568.  
  569.                /*****************************
  570.                *
  571.                *  If the stack is not empty,
  572.                *  pop the coordinates of
  573.                *  the pixel off the stack
  574.                *  and check its 8 neighbors.
  575.                *
  576.                *******************************/
  577.  
  578.          while(stack_empty == 0){
  579.             pop_i = stack[pointer][0]; /* POP       */
  580.             pop_j = stack[pointer][1]; /* OPERATION */
  581.             --pointer;
  582.             if(pointer <= 0){
  583.                if(stack_file_in_use){
  584.                   pop_data_off_of_stack_file(
  585.                                  stack,
  586.                                  &pointer,
  587.                                  &stack_file_in_use);
  588.                }  /* ends if stack_file_in_use  */
  589.                else{
  590.                   pointer     = 0;
  591.                   stack_empty = 1;
  592.                }  /* ends else stack file is
  593.                      not in use  */
  594.             }  /*  ends if point <= 0  */
  595.             pixel_label_and_check_neighbor(input,
  596.                            output, &target, &sum,
  597.                            &count, stack, g_label,
  598.                            &stack_empty, &pointer,
  599.                            pop_i, pop_j,
  600.                            diff, &stack_file_in_use,
  601.                            &first_call);
  602.          }  /* ends while stack_empty == 0 */
  603.  
  604.          if(object_found == 1){
  605.             object_found = 0;
  606.  
  607.                   /**********************************
  608.                   *
  609.                   *  The object must be in the
  610.                   *  size constraints given by
  611.                   *  min_area and max_area
  612.                   *
  613.                   *********************************/
  614.  
  615.             if(count >= min_area  &&
  616.                count <= max_area)
  617.                ++g_label;
  618.                   /**********************************
  619.                   *
  620.                   *   Remove the object from the
  621.                   *   output.  Set all pixels in the
  622.                   *   object you are removing to
  623.                   *   FORGET_IT.
  624.                   *
  625.                   **********************************/
  626.  
  627.             else{
  628.                for(ii=0; ii<ROWS; ii++){
  629.                   for(jj=0; jj<COLS; jj++){
  630.                      if(output[ii][jj] == g_label){
  631.                         output[ii][jj] = 0;
  632.                         input[ii][jj]  = FORGET_IT;
  633.                      }  /* ends if output == g_label */
  634.                   }  /* ends loop over jj */
  635.                }  /* ends loop over ii */
  636.             }  /* ends else remove object */
  637.          }  /* ends if object_found == 1 */
  638.  
  639.       }   /* ends loop over j */
  640.    }  /* ends loop over i */
  641.  
  642.    printf("\nGROW> found %d objects", g_label);
  643.  
  644. } /* ends pixel_grow  */
  645.  
  646.  
  647.  
  648.  
  649.  
  650.    /********************************************
  651.    *
  652.    *  pixel_label_and_check_neighbors(...
  653.    *
  654.    *  This function labels a pixel with an object
  655.    *  label and then checks the pixel's 8
  656.    *  neighbors.  If any of the neigbors are
  657.    *  set, then they are also labeled.
  658.    *
  659.    *  It also updates the target or ave pixel
  660.    *  value of the pixels in the region being
  661.    *  grown.
  662.    *
  663.    ***********************************************/
  664. pixel_label_and_check_neighbor(input_image,
  665.                          output_image, target,
  666.                          sum, count, stack,
  667.                          g_label, stack_empty,
  668.                          pointer, r, e, diff,
  669.                          stack_file_in_use,
  670.                          first_call)
  671. int   *count,
  672.       e,
  673.       *first_call,
  674.       *pointer,
  675.       r,
  676.       *stack_empty,
  677.       *stack_file_in_use;
  678.  
  679. short input_image[ROWS][COLS],
  680.       output_image[ROWS][COLS],
  681.       g_label,
  682.       *sum,
  683.       *target,
  684.       stack[STACK_SIZE][2],
  685.       diff;
  686. {
  687.    int already_labeled = 0,
  688.        i, j;
  689.  
  690.    if (output_image[r][e] != 0)
  691.       already_labeled = 1;
  692.  
  693.    output_image[r][e] = g_label;
  694.    *count  = *count + 1;
  695.    if(*count > 1){
  696.       *sum    = *sum + input_image[r][e];
  697.       *target = *sum / *count;
  698.    }
  699.  
  700.       /***************************************
  701.       *
  702.       *   Look at the 8 neighors of the
  703.       *   point r,e.
  704.       *
  705.       *   Ensure the points are close enough
  706.       *   to the target and do not equal
  707.       *   FORGET_IT.
  708.       *
  709.       *   Ensure the points you are checking
  710.       *   are in the image, i.e. not less
  711.       *   than zero and not greater than
  712.       *   ROWS-1 or COLS-1.
  713.       *
  714.       ***************************************/
  715.  
  716.    for(i=(r-1); i<=(r+1); i++){
  717.       for(j=(e-1); j<=(e+1); j++){
  718.  
  719.          if((i>=0)   &&
  720.             (i<=ROWS-1)  &&
  721.             (j>=0)   &&
  722.             (j<=COLS-1)){
  723.  
  724.             if( input_image[i][j] != FORGET_IT   &&
  725.                 is_close(input_image[i][j],
  726.                             *target, diff)       &&
  727.                 output_image[i][j] == 0){
  728.                *pointer           = *pointer + 1;
  729.                stack[*pointer][0] = i; /* PUSH      */
  730.                stack[*pointer][1] = j; /* OPERATION */
  731.                *stack_empty       = 0;
  732.  
  733.                if(*pointer >= (STACK_SIZE -
  734.                                STACK_FILE_LENGTH)){
  735.                   push_data_onto_stack_file(stack,
  736.                             pointer, first_call);
  737.                   *stack_file_in_use = 1;
  738.                }  /* ends if *pointer >=
  739.                      STACK_SIZE - STACK_FILE_LENGTH*/
  740.  
  741.             }  /* ends if is_close */
  742.          }  /* end if i and j are on the image */
  743.       }  /* ends loop over i rows           */
  744.    }  /* ends loop over j columns        */
  745. }  /* ends pixel_label_and_check_neighbors  */
  746.  
  747.  
  748.  
  749.    /********************************************
  750.    *
  751.    *  is_close(...
  752.    *
  753.    *  This function tests to see if two pixel
  754.    *  values are close enough together.  It
  755.    *  uses the delta parameter to make this
  756.    *  judgement.
  757.    *
  758.    ***********************************************/
  759.  
  760. is_close(a, b, delta)
  761.    short a, b, delta;
  762. {
  763.    int   result = 0;
  764.    short diff;
  765.  
  766.    diff = a-b;
  767.    if(diff < 0) diff = diff*(-1);
  768.    if(diff < delta)
  769.       result = 1;
  770.    return(result);
  771. }  /* ends is_close */
  772.  
  773.  
  774.  
  775.  
  776.      /*******************************************
  777.      *
  778.      *   erode_image_array(..
  779.      *
  780.      *   This function erodes pixels.  If a pixel
  781.      *   equals value and has more than threshold
  782.      *   neighbors equal to 0, then set that
  783.      *   pixel in the output to 0.
  784.      *
  785.      *******************************************/
  786.  
  787.  
  788. erode_image_array(the_image, out_image,
  789.                   value, threshold)
  790.    short  the_image[ROWS][COLS],
  791.           out_image[ROWS][COLS],
  792.           threshold,
  793.           value;
  794. {
  795.    int    a, b, count, i, j, k,
  796.           length, width;
  797.  
  798.       /***************************
  799.       *
  800.       *   Loop over image array
  801.       *
  802.       ****************************/
  803.  
  804.    for(i=0; i<ROWS; i++)
  805.       for(j=0; j<COLS; j++)
  806.          out_image[i][j] = the_image[i][j];
  807.  
  808.    printf("\n");
  809.  
  810.    for(i=1; i<ROWS-1; i++){
  811.       if( (i%10) == 0) printf("%3d", i);
  812.       for(j=1; j<COLS-1; j++){
  813.          if(the_image[i][j] == value){
  814.             count = 0;
  815.             for(a=-1; a<=1; a++){
  816.                 for(b=-1; b<=1; b++){
  817.                       if(the_image[i+a][j+b] == 0)
  818.                          count++;
  819.                 }  /*  ends loop over b */
  820.             }  /* ends loop over a */
  821.             if(count > threshold) out_image[i][j] = 0;
  822.          }  /* ends if the_image == value */
  823.       }  /* ends loop over j */
  824.    }  /* ends loop over i */
  825.  
  826. }  /* ends erode_image_array */
  827.  
  828.  
  829.  
  830.  
  831.  
  832.    /********************************************
  833.    *
  834.    *  get_edge_region_options(...
  835.    *
  836.    *  This function interacts with the user to   
  837.    *  get the options needed to call the 
  838.    *  edge and region based segmentation 
  839.    *  routines.
  840.    *
  841.    ********************************************/
  842.  
  843. get_edge_region_options(method, edge_type, 
  844.          min_area, max_area, set_value, 
  845.          diff, percent, erode)
  846.    char  method[];
  847.    float *percent;
  848.    int   *edge_type;
  849.    short *diff, *erode, 
  850.          *min_area, *max_area, 
  851.          *set_value;
  852. {
  853.    int not_finished = 1, response;
  854.  
  855.    while(not_finished){
  856.       printf("\n\nEdge Region Segmentation Options:");
  857.       printf("\n\t1.  Method is %s", method);
  858.       printf("\n\t    Recall: Edge, Gray shade, "
  859.                       "Combination");
  860.       printf("\n\t2.  Edge type is %d", *edge_type);
  861.       printf("\n\t    Recall: ");
  862.       printf("\n\t     1=Prewitt     2=Kirsch");
  863.       printf("\n\t     3=Sobel       4=quick");
  864.       printf("\n\t     5=homogeneity 6=difference");
  865.       printf("\n\t     7=contrast    8=gaussian");
  866.       printf("\n\t     10=range      11=variance");
  867.       printf("\n\t3.  Min area is %d", *min_area);
  868.       printf("\n\t4.  Max area is %d", *max_area);
  869.       printf("\n\t5.  Set value is %d", *set_value);
  870.       printf("\n\t6.  Difference value is %d", *diff);
  871.       printf("\n\t7.  Threshold percentage is %f",
  872.                       *percent);
  873.       printf("\n\t8.  Erode is %d", *erode);
  874.       printf("\n\nEnter choice (0 = no change) _\b");
  875.  
  876.       get_integer(&response);
  877.  
  878.       if(response == 0){
  879.         not_finished = 0;
  880.       }
  881.  
  882.       if(response == 1){
  883.          printf("\n\t    Recall: Edge, Gray shade, "
  884.                          "Combination");
  885.          printf("\n\t> ");
  886.          gets(method);
  887.       }
  888.  
  889.       if(response == 2){
  890.          printf("\n\t    Recall:"); 
  891.          printf("\n\t     1=Prewitt     2=Kirsch");
  892.          printf("\n\t     3=Sobel       4=quick");
  893.          printf("\n\t     5=homogeneity 6=difference");
  894.          printf("\n\t     7=contrast    8=gaussian");
  895.          printf("\n\t     10=range      11=variance");
  896.          printf("\n\t__\b");
  897.          get_integer(edge_type);
  898.       }
  899.  
  900.       if(response == 3){
  901.          printf("\nEnter min area:__\b\b");
  902.          get_integer(min_area);
  903.       }
  904.  
  905.       if(response == 4){
  906.          printf("\nEnter max area:__\b\b");
  907.          get_integer(max_area);
  908.       }
  909.  
  910.       if(response == 5){
  911.          printf("\nEnter set value:__\b\b");
  912.          get_integer(set_value);
  913.       }
  914.  
  915.       if(response == 6){
  916.          printf("\nEnter difference:__\b\b");
  917.          get_integer(diff);
  918.       }
  919.  
  920.       if(response == 7){
  921.          printf("\nEnter threshold percentage:__\b\b");
  922.          get_float(percent);
  923.       }
  924.  
  925.       if(response == 8){
  926.          printf("\nEnter erode:__\b\b");
  927.          get_integer(erode);
  928.       }
  929.  
  930.    }  /* ends while not_finished */
  931. }  /* ends get_edge_region_options */
  932.